home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / indeo / dgvpla / dgvplayr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-29  |  49.1 KB  |  1,449 lines

  1. /********************************************************************
  2.  
  3.    PROGRAM: DGVPLAYR.C
  4.  
  5.    PURPOSE: Video Player 
  6.  
  7.    Amended by Bob Ashmore Compuserve id 100024,1753
  8.  
  9.    
  10.    This code allows more than 1 instance of the video driver to display
  11.    at a time. All data for the Driver Instance for the current window
  12.    is held in the Instance windows property list. I have also allowed 
  13.    the user to load and play AVI files,the only problem I encountered 
  14.    with AVI was that you could not pause the avi driver after it was 
  15.    loaded.
  16.    I also put in a dialog box to control the driver so as people can
  17.    see how its done. I have put in an option to go 1 frame backward 
  18.    this can take quite some time to execute due to the fact that I
  19.    go back to the previous reference frame and play forward to the 
  20.    current frame. I have encountered some problems with the freeze
  21.    option when the window is misaligned ie it goes black. I tried to
  22.    make the video windows a child of the main window but when you
  23.    move the parent the video area is corrupted. I have also opened the
  24.    driver before I open the window so I can obtain the size of the
  25.    source bitmap and make the window the same size when I create it.
  26.    The code is very rough and ready since this is my first encounter
  27.    with windows programming and its a bit overwelming at first. I 
  28.    whould love to be able to change the menu to a set of owner draw
  29.    buttons like a VCR but I dont yet no how any help is welcome. I hope 
  30.    this code is of some use to people. I have also allowed the user to
  31.    suspend an instance of the driver as discribed in the documentation
  32.    and it works.You can load about 3 stills at 1 time or 1 movie and
  33.    2 stills. if you want 2 movies you can load 1 movie and suspend it
  34.    then load the second of course only 1 can be active at 1 time.Its 
  35.    quite impressive to see an avi movie and an avs movie playing in
  36.    overlaping windows at the same time.
  37. ********************************************************************/
  38.  
  39. #define  NOCOMM
  40. #define  WINVER 0x0300
  41.  
  42. #include <windows.h>
  43. #include <stdlib.h>
  44. #include <direct.h>
  45. #include <string.h>
  46. #include <commdlg.h>
  47. #include <mmsystem.h>
  48. #include <digitalv.h>
  49. #include "dgvplayr.h"
  50.  
  51. static HWND    hMainWnd;                  // Main window handle
  52. static HWND    hArrVideoWnd[10];          // Up to 10 driver windows
  53. static HWND    hCurrentVideoWnd;          // Current window handle
  54. static short   vInstNum=1;                // Unique number for Instance
  55. char           szvPropEntry[] = "DVIDRV"; // Property entry name 
  56. static char    DVIFilename[_MAX_PATH];    // AVSS file name
  57. static char    szAppName[] = "DgvPlayer"; // Aplication name
  58. HANDLE         hInst;                     // Handle to current instance
  59. static char    szFileName[128];           // Filename of AVSS file
  60. static char    szDirName[256];            // Directory name
  61. static char    szDriverName[256];         // Driver name
  62. static char    szMainClass[]  = "dgmclass"; // Class name for Main window
  63. static char    szVideoClass[] = "dgvclass"; // Class name for video windows
  64. static char    szMainMenu[]   = "dvimain";  // Menu name for Main window
  65. static char    szVideoMenu[]  = "dviplay";  // Menu name for video windows
  66. static HCURSOR hcurWait = NULL;             //- hourglass cursor
  67. static HCURSOR hcurSaved;                   //- old cursor
  68.  
  69. // Local Function Prototypes 
  70.  
  71. LONG FAR PASCAL DVIWndProc(HWND, unsigned, WORD, LONG);
  72. LONG FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
  73. static BOOL InitApplication(HANDLE hInstance);
  74. static BOOL InitInstance(HANDLE hInstance, int nCmdShow);
  75. BOOL GetFileName (LPSTR szFileName);
  76. static void UpdateMenus(HWND);
  77. static void DisableMenus(HWND hwnd);
  78. static void DisplayError(HWND, DWORD);
  79. void OpenVideoWindow (LPSTR szTitle, HWND hOwner);
  80. int StoreChildHandle(HWND hwnd);
  81. int FreeChildHandle(HWND hwnd);
  82. int VidsOpen(void);
  83. BOOL FAR PASCAL AboutDlg(HWND hDlg, unsigned message,
  84.                         WORD wParam, LONG lParam);
  85. BOOL FAR PASCAL DriverDlg(HWND hDlg, unsigned message,
  86.                         WORD wParam, LONG lParam);
  87.  
  88.  
  89. /********************************************************************
  90.  
  91.    FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
  92.  
  93.    PURPOSE: Standard MS Windows main window funtion.
  94. ********************************************************************/
  95. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  96.                    LPSTR lpCmdLine, int nCmdShow)
  97. {
  98.  
  99.    MSG   msg;
  100.    WORD  wMessage;
  101.  
  102.    // Register classes if we are the first instance
  103.  
  104.    if(!hPrevInstance)
  105.       if(!InitApplication(hInstance))  // Initialize shared things
  106.          return(FALSE);                // Exit if unable to initialize
  107.  
  108.    // Perform initializations that apply to a specific instance
  109.  
  110.    if(!InitInstance(hInstance, nCmdShow))
  111.       return(FALSE);
  112.  
  113.    wMessage = RegisterWindowMessage((LPSTR)"MCIERR_HARDWARE");
  114.    if(!wMessage)
  115.       {
  116.       MessageBox(GetFocus(),
  117.          "Unable to register window message MCIERR_HARDWARE - terminating",
  118.          szAppName,
  119.          MB_ICONASTERISK | MB_OK);
  120.       return FALSE;
  121.       }
  122.  
  123.    // Acquire and dispatch messages until a WM_QUIT message is received 
  124.  
  125.    while(GetMessage(&msg, NULL, 0, 0))
  126.       {
  127.       // trap the System Shutdown message here.  If found, send        
  128.       // our main window proc a message telling it to close down.   
  129.       // Any other messages we process as normal.                   
  130.  
  131.       if(msg.message == wMessage)
  132.          PostMessage(hMainWnd, WMU_SYSTEMSHUTDOWN, 0, 0L);
  133.       else
  134.           {
  135.          TranslateMessage(&msg);    // Translates virtual key codes 
  136.          DispatchMessage(&msg);     // Dispatches message to window 
  137.          }
  138.       }
  139.  
  140.    return(msg.wParam);  // Return the value from PostQuitMessage 
  141. }
  142.  
  143. /********************************************************************
  144.  
  145.    FUNCTION: InitApplication(HANDLE)
  146.  
  147.    PURPOSE: Initializes window data and registers window class
  148. ********************************************************************/
  149. static BOOL InitApplication(HANDLE hInstance)
  150. {
  151.  
  152.    WNDCLASS    wc;
  153.  
  154.    wc.style         = NULL;
  155.    wc.lpfnWndProc   = (WNDPROC)MainWndProc;
  156.    wc.cbClsExtra    = 0;
  157.    wc.cbWndExtra    = 0;
  158.    wc.hInstance     = hInstance;
  159.    wc.hIcon         = NULL;
  160.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  161.    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  162.    wc.lpszMenuName  = szMainMenu;
  163.    wc.lpszClassName = szMainClass;
  164.  
  165.     if(!RegisterClass(&wc))
  166.         return FALSE;
  167.  
  168.    wc.style         = NULL;
  169.    wc.lpfnWndProc   = (WNDPROC)DVIWndProc;
  170.    wc.cbClsExtra    = 0;
  171.    wc.cbWndExtra    = 0;
  172.    wc.hInstance     = hInstance;
  173.    wc.hIcon         = LoadIcon(hInstance, "playback");
  174.    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
  175.    wc.hbrBackground = GetStockObject(BLACK_BRUSH);
  176.    wc.lpszMenuName  = NULL;  //szVideoMenu;
  177.    wc.lpszClassName = szVideoClass;
  178.  
  179.     if(!RegisterClass(&wc))
  180.       {
  181.       UnregisterClass (szMainClass, hInstance);
  182.         return FALSE;
  183.       }
  184.  
  185.    hcurWait = LoadCursor(NULL, IDC_WAIT);
  186.  
  187.    return TRUE;
  188. }
  189.  
  190. /********************************************************************
  191.  
  192.    FUNCTION: InitInstance(HANDLE, int)
  193.  
  194.    PURPOSE:  Saves instance handle and creates main window
  195.  
  196. ********************************************************************/
  197. static BOOL InitInstance(HANDLE hInstance, int nCmdShow)
  198. {
  199.  
  200.    HDC      hDC;
  201.    int      cxScr,cyScr,i;
  202.  
  203.    for(i=0;i<10;i++)
  204.       hArrVideoWnd[i] = NULL;             // Setup the child window handles
  205.  
  206.    hDC   = GetDC (NULL);                  // Get the DC for whole screen
  207.    cxScr = GetDeviceCaps (hDC, HORZRES);  // Get the Screen width
  208.    cyScr = GetDeviceCaps (hDC, VERTRES);  // Get the Screen length
  209.    ReleaseDC (NULL, hDC);                 // Release Screen DC
  210.    hInst = hInstance;                     // Save the instance handle
  211.  
  212.    hMainWnd = CreateWindow(szMainClass,
  213.       szAppName,                        // Text for window title bar.
  214.       WS_OVERLAPPEDWINDOW |               // Window style.
  215.       WS_CLIPCHILDREN,
  216.       0,                                  // Default horizontal position.
  217.       0,                                  // Default vertical position.
  218.       cxScr,                              // Default width.
  219.       cyScr,                              // Default height.
  220.       NULL,                               // Overlapped windows have no parent.
  221.       NULL,                               // Use the window class menu.        
  222.       hInstance,                          // This instance owns this window.   
  223.       NULL);                              // Pointer not needed.               
  224.  
  225.    // Make the window visible and update its client area 
  226.  
  227.    ShowWindow(hMainWnd, nCmdShow);         // Show the window                        
  228.    UpdateWindow(hMainWnd);                 // Sends WM_PAINT message
  229.    return(TRUE);
  230. }
  231.  
  232.  
  233. /********************************************************************
  234.  
  235.    FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
  236.  
  237.    PURPOSE:  This is the callback function for the main window
  238.  
  239. ********************************************************************/
  240. LONG FAR PASCAL MainWndProc(HWND hwnd, unsigned message,
  241.                             WORD wParam, LONG lParam)
  242. {
  243.    
  244.    char     Rtn[256];
  245.    DWORD    Result;
  246.    int      i;
  247.  
  248.    switch(message)
  249.       {
  250.       case WMU_SYSTEMSHUTDOWN:
  251.          // After an System Shutdown we must close the driver            
  252.          // to protect system integrity.  We display a message at this  
  253.          // point telling users that they may open a new file.          
  254.  
  255.          // Some shutdowns cause us to lose focus, so get it back.        
  256.  
  257.            SetFocus(hwnd);    
  258.  
  259.            // Tell the user we're shutting down. 
  260.  
  261.          MessageBox(NULL,
  262.             "A System Shutdown has occurred and all files are being closed. You may select a new file to be played or exit.",
  263.             "Sample Player Demonstration",
  264.             MB_ICONASTERISK | MB_OK);
  265.  
  266.          // Close down all driver instances. 
  267.          
  268.          for(i=0;i<10;i++)
  269.             if(hArrVideoWnd[i] != NULL)
  270.                {
  271.                SendMessage(hArrVideoWnd[i], WM_CLOSE, 0, 0L);
  272.                hArrVideoWnd[i] = NULL;
  273.                }
  274.          hCurrentVideoWnd = NULL;
  275.  
  276.          // Close down all drivers. 
  277.  
  278.          Result = mciSendString("close all", Rtn, sizeof(Rtn),(HANDLE)hwnd);
  279.             if(Result)
  280.                DisplayError(hwnd, Result);
  281.  
  282.            break; 
  283.  
  284.       case WM_COMMAND:
  285.          switch(wParam)
  286.             {
  287.             case DVM_MOD:
  288.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_MOD, 0L);
  289.                break;
  290.             case DVM_SUS:
  291.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_SUS, 0L);
  292.                break;
  293.             case DVM_EXIT:
  294.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_EXIT, 0L);
  295.                break;
  296.  
  297.             case DVM_PLAY:
  298.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_PLAY, 0L);
  299.                break;
  300.             case DVM_PAUSE:
  301.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_PAUSE, 0L);
  302.                break;
  303.             case DVM_REWIND:
  304.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_REWIND, 0L);
  305.                break;
  306.             case DVM_STEP:
  307.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_STEP, 0L);
  308.                break;
  309.             case DVM_REVERSE:
  310.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_REVERSE, 0L);
  311.                break;
  312.  
  313.             case IDM_OPEN:
  314.                // The user wants to open a driver instance so go get an
  315.                // AVSS file using the 3.1 common file dialog
  316.                if(GetFileName (szFileName))
  317.                   OpenVideoWindow ((LPSTR)szFileName,NULL); //Open driver instance
  318.                break;
  319.  
  320.             case IDM_EXIT:
  321.                for(i=0;i<10;i++)
  322.                   if(hArrVideoWnd[i] != NULL)
  323.                      SendMessage(hArrVideoWnd[i], WM_CLOSE, 0, 0L);
  324.                Result = mciSendString("close all", Rtn, sizeof(Rtn),(HANDLE)hwnd);
  325.                if(Result)
  326.                   DisplayError(hwnd, Result);
  327.                SendMessage (hwnd, WM_CLOSE, 0, 0L);
  328.                break;
  329.  
  330.             case IDM_ABOUT:
  331.                break;
  332.  
  333.             default:
  334.                return(DefWindowProc(hwnd, message, wParam, lParam));
  335.             }
  336.          break;
  337.       case WM_MOVE:
  338.       case WM_SIZE:
  339.          SetWindowPos(hCurrentVideoWnd,hMainWnd,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
  340.          break;
  341.        case WM_PAINT :
  342.          SendMessage(hCurrentVideoWnd, WM_PAINT, 0, 0L);
  343.          return(DefWindowProc(hwnd, message, wParam, lParam));
  344.  
  345.       case WM_CLOSE:
  346.          DestroyWindow(hwnd);
  347.          break;
  348.  
  349.       case WM_DESTROY:
  350.          PostQuitMessage(0);
  351.          return 0;
  352.  
  353.       default:
  354.          return(DefWindowProc(hwnd, message, wParam, lParam));
  355.       }
  356.  
  357.    return(0);
  358. }
  359.  
  360. /********************************************************************
  361.  
  362.    FUNCTION: OpenVideoWindow (LPSTR szTitle, HWND hOwner)
  363.  
  364.    PURPOSE:  This creates a new video window and opens a new
  365.              instance of the driver.
  366.  
  367. ********************************************************************/
  368. void OpenVideoWindow (LPSTR szFile, HWND hOwner)
  369. {
  370.    HWND     hwnd;
  371.    HDC      hDC;
  372.    int      cxScr,cyScr;
  373.    char     Cmd[256];
  374.    char     Rtn[256];
  375.    DWORD    Result;
  376.    RECT     CurRect;
  377.    RECT     NewRect;
  378.    HANDLE   hMem;
  379.    PSTR     pMem;
  380.    HMENU    hMenu;
  381.    long     lFrameNo;
  382.    int      i,nArray[4];
  383.    char     *ptr,*ptr1;
  384.    vidwin_t *vData;
  385.    RECT     rect;
  386.  
  387.  
  388.    lstrcpy(DVIFilename,szFile);
  389.  
  390.    hcurSaved = SetCursor(hcurWait);
  391.    hMem = LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,sizeof(vidwin_t));
  392.    pMem = LocalLock(hMem);
  393.    vData = (vidwin_t *)pMem;
  394.    vData->vInstNum = vInstNum++;
  395.    wsprintf(vData->vIname, "%s%u",(LPSTR) "DVI",vData->vInstNum);
  396.    wsprintf(Cmd, "open %s alias %s",(LPSTR) DVIFilename,(LPSTR)vData->vIname);
  397.    Result = mciSendString(Cmd, Rtn, sizeof(Rtn), NULL);
  398.    if(Result)
  399.       {
  400.       DisplayError(hwnd, Result);
  401.       SetCursor(hcurSaved);
  402.       return;
  403.       }
  404.    wsprintf(Cmd, "where %s source",(LPSTR)vData->vIname);
  405.    Result = mciSendString(Cmd, Rtn, sizeof(Rtn), NULL);
  406.    if(Result)
  407.       {
  408.       DisplayError(hwnd, Result);
  409.       SetCursor(hcurSaved);
  410.       return;
  411.       }
  412.    ptr = ptr1 = Rtn;
  413.    i=0;
  414.    while(*ptr)
  415.       {
  416.       if(*ptr == 32)
  417.          {
  418.          *ptr = 0;
  419.          nArray[i++] = atoi(ptr1);
  420.          ptr1 = ptr+1;
  421.          }
  422.       ptr++;
  423.       }
  424.    nArray[i] = atoi(ptr1);
  425.    hwnd = CreateWindow(szVideoClass,
  426.                            szFile,
  427.                            WS_OVERLAPPEDWINDOW,
  428.                            40+(VidsOpen() * 30),
  429.                            64+(VidsOpen() * 24),
  430.                            nArray[2],
  431.                            nArray[3],
  432.                            hMainWnd, 
  433.                            NULL, 
  434.                            hInst, 
  435.                            NULL);
  436.  
  437.    if(!hwnd)
  438.       return;
  439.  
  440.    strcpy(vData->DVIFilename,DVIFilename);
  441.    vData->State          = PAUSING;
  442.    vData->wVolume        = 500;
  443.    vData->lFrameNo       = 1;
  444.    vData->lStatusFrameNo = 1;
  445.    vData->wAudon         = TRUE;
  446.    vData->wVidon         = TRUE;
  447.    vData->hWnd = hwnd;
  448.    // Get the size of the source bitmap
  449.  
  450.    SetProp(hwnd,(LPSTR) szvPropEntry,hMem);
  451.    wsprintf(Cmd, "window %s handle %u",(LPSTR)vData->vIname,hwnd);
  452.    Result = mciSendString(Cmd, Rtn, sizeof(Rtn), hwnd);
  453.    if(Result)
  454.       {
  455.       DisplayError(hwnd, Result);
  456.       SetCursor(hcurSaved);
  457.       return;
  458.       }
  459.    wsprintf(Cmd, "pause %s notify",(LPSTR)vData->vIname);
  460.    Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  461.    if(Result)
  462.       {
  463.       // AVI files will not allow a pause at the start ???
  464.       wsprintf(Cmd, "play %s notify",(LPSTR)vData->vIname);
  465.       Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  466.       if(Result)
  467.          {
  468.          DisplayError(hwnd, Result);
  469.          LocalUnlock(hMem);
  470.          return;
  471.          }
  472.       vData->State = PLAYING;
  473.       }
  474.    LocalUnlock(hMem);
  475.    DisableMenus(hwnd);
  476.    SetCursor(LoadCursor(NULL, IDC_ARROW));
  477.    StoreChildHandle(hwnd);          //Save the child and make current
  478.    SetCursor(hcurSaved);
  479.  
  480.    // Make the window visible and update its client area 
  481.  
  482.    ShowWindow(hwnd, SW_SHOWNORMAL);    // Show the window 
  483.    UpdateWindow (hwnd);
  484.    UpdateMenus(hMainWnd);
  485.    
  486. }
  487.  
  488. /********************************************************************
  489.  
  490.    FUNCTION: DVIWndProc(HWND, unsigned, WORD, LONG)
  491.  
  492.    PURPOSE:  This is the callback function for the Video window's
  493.  
  494. ********************************************************************/
  495. LONG FAR PASCAL DVIWndProc(HWND hwnd, unsigned message,
  496.                             WORD wParam, LONG lParam)
  497. {
  498.    FARPROC  lpDlgProc;
  499.    char     Cmd[256];
  500.    char     Rtn[256];
  501.    DWORD    Result;
  502.    RECT     CurRect;
  503.    RECT     NewRect;
  504.    HANDLE   hMem;
  505.    PSTR     pMem;
  506.    HMENU    hMenu;
  507.    long     lFrameNo,lStatusFrameNo;
  508.    int      i,nArray[4];
  509.    char     *ptr,*ptr1;
  510.    vidwin_t *vData;
  511.    RECT     rect;
  512.    
  513.    switch(message)
  514.       {
  515.       case MM_MCINOTIFY:
  516.  
  517.          // MCI Notify message, get after play, rewind, or step is done. 
  518.          // This window was specified in the callback of mciSendString. 
  519.          switch(wParam)
  520.             {
  521.             case MCI_NOTIFY_SUPERSEDED:
  522.                break;
  523.  
  524.             case MCI_NOTIFY_SUCCESSFUL:
  525.             case MCI_NOTIFY_ABORTED:
  526.             case MCI_NOTIFY_FAILURE:
  527.  
  528.             // if we are closing a file due to a System Shutdown, 
  529.             // do nothing here. 
  530.  
  531.             hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  532.             pMem = LocalLock(hMem);
  533.             vData = (vidwin_t *)pMem;
  534.                if(vData->State == CLOSED || vData->State == SUSPENDED)
  535.                {
  536.                LocalUnlock(hMem);
  537.                   break;
  538.                }
  539.             // now in a paused state 
  540.  
  541.  
  542.  
  543.             if(vData->State == PLAYING)
  544.                vData->State = END;      // we're at the end of the file 
  545.             else
  546.                vData->State = PAUSED;   // we've reached a known state 
  547.             LocalUnlock(hMem);
  548.  
  549.             UpdateMenus(hMainWnd);
  550.             break;
  551.             }
  552.          break;
  553.  
  554.       case WM_COMMAND:
  555.          switch(wParam)
  556.             {
  557.             case DVM_SUS:
  558.                // Will now suspend this Instance of the driver
  559.                hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  560.                pMem = LocalLock(hMem);
  561.                vData = (vidwin_t *)pMem;
  562.                if(vData->State != SUSPENDED)
  563.                   {
  564.                   wsprintf(Cmd, "pause %s",(LPSTR)vData->vIname);
  565.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  566.                   if(Result)
  567.                      {
  568.                      DisplayError(hwnd, Result);
  569.                      LocalUnlock(hMem);
  570.                      break;
  571.                      }
  572.                   wsprintf(Cmd, "status %s position",(LPSTR)vData->vIname);
  573.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  574.                   if(Result)
  575.                      {
  576.                      DisplayError(hwnd, Result);
  577.                      LocalUnlock(hMem);
  578.                      break;
  579.                      }
  580.                   vData->lFrameNo = atol(Rtn);
  581.                   wsprintf(Cmd, "status %s reference %ld",(LPSTR)vData->vIname,vData->lFrameNo);
  582.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  583.                   if(Result)
  584.                      {
  585.                      DisplayError(hwnd, Result);
  586.                      LocalUnlock(hMem);
  587.                      break;
  588.                      }
  589.                   vData->lStatusFrameNo = atol(Rtn);
  590.                   wsprintf(Cmd, "status %s volume",(LPSTR)vData->vIname);
  591.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  592.                   if(Result)
  593.                      {
  594.                      DisplayError(hwnd, Result);
  595.                      LocalUnlock(hMem);
  596.                      break;
  597.                      }
  598.                   vData->wVolume = atoi(Rtn);               
  599.                   wsprintf(Cmd, "status %s audio",(LPSTR)vData->vIname);
  600.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  601.                   if(Result)
  602.                      {
  603.                      DisplayError(hwnd, Result);
  604.                      LocalUnlock(hMem);
  605.                      break;
  606.                      }
  607.                   if(!stricmp(Rtn,"on"))
  608.                      vData->wAudon = TRUE;               
  609.                   else
  610.                      vData->wAudon = FALSE;               
  611.                   wsprintf(Cmd, "status %s video",(LPSTR)vData->vIname);
  612.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  613.                   if(Result)
  614.                      {
  615.                      DisplayError(hwnd, Result);
  616.                      LocalUnlock(hMem);
  617.                      break;
  618.                      }
  619.                   if(!stricmp(Rtn,"on"))
  620.                      vData->wVidon = TRUE;               
  621.                   else
  622.                      vData->wVidon = FALSE;               
  623.                   wsprintf(Cmd, "close %s",(LPSTR)vData->vIname);
  624.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  625.                   if(Result)
  626.                      {
  627.                      DisplayError(hwnd, Result);
  628.                      LocalUnlock(hMem);
  629.                      break;
  630.                      }
  631.                   vData->State = SUSPENDED;
  632.                   hMenu = GetMenu(hwnd);
  633.                   ModifyMenu(hMenu,DVM_SUS,MF_BYCOMMAND,DVM_SUS,(LPSTR)"Resume");
  634.                   LocalUnlock(hMem);
  635.                   DisableMenus(hwnd);
  636.                   break;
  637.                   }
  638.                else
  639.                   {
  640.                   // Will now resume this Instance of the driver
  641.                   hcurSaved = SetCursor(hcurWait);
  642.                   hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  643.                   pMem = LocalLock(hMem);
  644.                   vData = (vidwin_t *)pMem;
  645.                   
  646.                   if(vData->State != SUSPENDED)
  647.                      {
  648.                      MessageBox(GetFocus(),
  649.                      "This Driver is not Suspended",
  650.                      szAppName,
  651.                      MB_ICONASTERISK | MB_OK);
  652.                      LocalUnlock(hMem);
  653.                      break;
  654.                      }
  655.                   
  656.                   wsprintf(Cmd, "open %s alias %s",(LPSTR) vData->DVIFilename,(LPSTR)vData->vIname);
  657.                   Result = mciSendString(Cmd, Rtn, sizeof(Rtn), hwnd);
  658.                   if(Result)
  659.                      {
  660.                      DisplayError(hwnd, Result);
  661.                      LocalUnlock(hMem);
  662.                      break;
  663.                      }
  664.                   
  665.                   wsprintf(Cmd, "window %s handle %u",(LPSTR)vData->vIname,hwnd);
  666.                   Result = mciSendString(Cmd, Rtn, sizeof(Rtn), hwnd);
  667.                   if(Result)
  668.                      {
  669.                      DisplayError(hwnd, Result);
  670.                      LocalUnlock(hMem);
  671.                      break;
  672.                      }
  673.                   wsprintf(Cmd, "setaudio %s off",(LPSTR)vData->vIname);
  674.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  675.                   if(Result)
  676.                      {
  677.                      DisplayError(hwnd, Result);
  678.                      LocalUnlock(hMem);
  679.                      break;
  680.                      }
  681.                   wsprintf(Cmd, "freeze %s",(LPSTR)vData->vIname);
  682.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  683.                   if(Result)
  684.                      {
  685.                      DisplayError(hwnd, Result);
  686.                      LocalUnlock(hMem);
  687.                      break;
  688.                      }
  689.  
  690.                   wsprintf(Cmd, "seek %s to %ld",(LPSTR)vData->vIname,vData->lStatusFrameNo);
  691.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  692.                   if(Result)
  693.                      {
  694.                      DisplayError(hwnd, Result);
  695.                      LocalUnlock(hMem);
  696.                      break;
  697.                      }
  698.                   wsprintf(Cmd, "play %s to %ld wait",(LPSTR)vData->vIname,vData->lFrameNo);
  699.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  700.                   if(Result)
  701.                      {
  702.                      DisplayError(hwnd, Result);
  703.                      LocalUnlock(hMem);
  704.                      break;
  705.                      }
  706.                   wsprintf(Cmd, "unfreeze %s",(LPSTR)vData->vIname);
  707.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  708.                   if(Result)
  709.                      {
  710.                      DisplayError(hwnd, Result);
  711.                      LocalUnlock(hMem);
  712.                      break;
  713.                      }
  714.                   wsprintf(Cmd, "setaudio %s volume to %d",(LPSTR)vData->vIname,vData->wVolume);
  715.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  716.                   if(Result)
  717.                      {
  718.                      DisplayError(hwnd, Result);
  719.                      LocalUnlock(hMem);
  720.                      break;
  721.                      }
  722.                   if(vData->wAudon == TRUE)
  723.                      wsprintf(Cmd, "setaudio %s on",(LPSTR)vData->vIname);
  724.                   else
  725.                      wsprintf(Cmd, "setaudio %s off",(LPSTR)vData->vIname);
  726.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  727.                   if(Result)
  728.                      {
  729.                      DisplayError(hwnd, Result);
  730.                      LocalUnlock(hMem);
  731.                      break;
  732.                      }
  733.                   if(vData->wVidon == TRUE)
  734.                      wsprintf(Cmd, "setvideo %s on",(LPSTR)vData->vIname);
  735.                   else
  736.                      wsprintf(Cmd, "setvideo %s off",(LPSTR)vData->vIname);
  737.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  738.                   if(Result)
  739.                      {
  740.                      DisplayError(hwnd, Result);
  741.                      LocalUnlock(hMem);
  742.                      break;
  743.                      }
  744.                   vData->State    = PAUSING;
  745.                   wsprintf(Cmd, "pause %s notify",(LPSTR)vData->vIname);
  746.                   Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  747.                   if(Result)
  748.                      {
  749.                      DisplayError(hwnd, Result);
  750.                      LocalUnlock(hMem);
  751.                      break;
  752.                      }
  753.                   LocalUnlock(hMem);
  754.                   hMenu = GetMenu(hwnd);
  755.                   ModifyMenu(hMenu,DVM_SUS,MF_BYCOMMAND,DVM_SUS,(LPSTR)"Suspend");
  756.                   SetCursor(hcurSaved);
  757.                   break;
  758.                   }
  759.             case DVM_MOD:
  760.                lpDlgProc = MakeProcInstance(DriverDlg, hInst);
  761.                DialogBox(hInst, "DriverMod", hwnd, lpDlgProc);
  762.                FreeProcInstance(lpDlgProc);
  763.                break;
  764.  
  765.             case DVM_DEFAULT:
  766.  
  767.                // Restore window to default size 
  768.  
  769.                GetWindowRect(hwnd, &CurRect);
  770.                SetRect(&NewRect, 0, 0, 319, 239);
  771.                AdjustWindowRect(&NewRect, WS_OVERLAPPEDWINDOW, TRUE);
  772.                MoveWindow(hwnd,
  773.                           CurRect.left, 
  774.                           CurRect.top,
  775.                           NewRect.right - NewRect.left,
  776.                           NewRect.bottom - NewRect.top + 1,
  777.                           TRUE);
  778.                break;
  779.  
  780.             case DVM_PAUSE:
  781.                hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  782.                pMem = LocalLock(hMem);
  783.                vData = (vidwin_t *)pMem;
  784.                wsprintf(Cmd, "pause %s notify",(LPSTR)vData->vIname);
  785.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  786.                if(Result)
  787.                   {
  788.                   DisplayError(hwnd, Result);
  789.                   LocalUnlock(hMem);
  790.                   break;
  791.                   }
  792.                vData->State = PAUSING;
  793.                LocalUnlock(hMem);
  794.                DisableMenus(hwnd);
  795.                break;
  796.  
  797.             case DVM_PLAY:
  798.                hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  799.                pMem = LocalLock(hMem);
  800.                vData = (vidwin_t *)pMem;
  801.                wsprintf(Cmd, "play %s notify",(LPSTR)vData->vIname);
  802.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  803.                if(Result)
  804.                   {
  805.                   DisplayError(hwnd, Result);
  806.                   LocalUnlock(hMem);
  807.                   break;
  808.                   }
  809.                vData->State = PLAYING;
  810.                LocalUnlock(hMem);
  811.                UpdateMenus(hMainWnd);
  812.                break;
  813.  
  814.             case DVM_REWIND:
  815.                hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  816.                pMem = LocalLock(hMem);
  817.                vData = (vidwin_t *)pMem;
  818.                wsprintf(Cmd, "seek %s to start notify",(LPSTR)vData->vIname);
  819.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  820.                if(Result)
  821.                   {
  822.                   DisplayError(hwnd, Result);
  823.                   LocalUnlock(hMem);
  824.                   break;
  825.                   }
  826.                vData->State = REWINDING;
  827.                LocalUnlock(hMem);
  828.                DisableMenus(hwnd);
  829.                break;
  830.  
  831.             case DVM_STEP:
  832.                hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  833.                pMem = LocalLock(hMem);
  834.                vData = (vidwin_t *)pMem;
  835.                wsprintf(Cmd, "step %s notify",(LPSTR)vData->vIname);
  836.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  837.                if(Result)
  838.                   {
  839.                   DisplayError(hwnd, Result);
  840.                   LocalUnlock(hMem);
  841.                   break;
  842.                   }
  843.                vData->State = STEPPING;
  844.                LocalUnlock(hMem);
  845.                DisableMenus(hwnd);
  846.                break;
  847.  
  848.             case DVM_REVERSE:
  849.                // This code allows you to go back 1 frame but because
  850.                // of the nature of the compression system it is very 
  851.                // slow due to the workaround I have to use.
  852.  
  853.                hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  854.                pMem = LocalLock(hMem);
  855.                vData = (vidwin_t *)pMem;
  856.                hcurSaved = SetCursor(hcurWait);
  857.                wsprintf(Cmd, "pause %s",(LPSTR)vData->vIname);
  858.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  859.                if(Result)
  860.                   {
  861.                   DisplayError(hwnd, Result);
  862.                   LocalUnlock(hMem);
  863.                   break;
  864.                   }
  865.                wsprintf(Cmd, "freeze %s",(LPSTR)vData->vIname);
  866.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  867.                if(Result)
  868.                   {
  869.                   DisplayError(hwnd, Result);
  870.                   LocalUnlock(hMem);
  871.                   break;
  872.                   }
  873.                wsprintf(Cmd, "setaudio %s off",(LPSTR)vData->vIname);
  874.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  875.                if(Result)
  876.                   {
  877.                   DisplayError(hwnd, Result);
  878.                   LocalUnlock(hMem);
  879.                   break;
  880.                   }
  881.                wsprintf(Cmd, "status %s position",(LPSTR)vData->vIname);
  882.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  883.                if(Result)
  884.                   {
  885.                   DisplayError(hwnd, Result);
  886.                   LocalUnlock(hMem);
  887.                   break;
  888.                   }
  889.                lFrameNo = (atol(Rtn)) - 1;
  890.                wsprintf(Cmd, "status %s reference %ld",(LPSTR)vData->vIname,lFrameNo);
  891.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  892.                if(Result)
  893.                   {
  894.                   DisplayError(hwnd, Result);
  895.                   LocalUnlock(hMem);
  896.                   break;
  897.                   }
  898.                lStatusFrameNo = atol(Rtn);
  899.                vData->State = STEPPING;
  900.                wsprintf(Cmd, "seek %s to %ld",(LPSTR)vData->vIname,lStatusFrameNo);
  901.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  902.                if(Result)
  903.                   {
  904.                   DisplayError(hwnd, Result);
  905.                   LocalUnlock(hMem);
  906.                   break;
  907.                   }
  908.                wsprintf(Cmd, "play %s to %ld wait",(LPSTR)vData->vIname,lFrameNo);
  909.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  910.                if(Result)
  911.                   {
  912.                   DisplayError(hwnd, Result);
  913.                   LocalUnlock(hMem);
  914.                   break;
  915.                   }
  916.                if(vData->wAudon == TRUE)
  917.                   wsprintf(Cmd, "setaudio %s on",(LPSTR)vData->vIname);
  918.                else
  919.                   wsprintf(Cmd, "setaudio %s off",(LPSTR)vData->vIname);
  920.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  921.                if(Result)
  922.                   {
  923.                   DisplayError(hwnd, Result);
  924.                   LocalUnlock(hMem);
  925.                   break;
  926.                   }
  927.                wsprintf(Cmd, "unfreeze %s",(LPSTR)vData->vIname);
  928.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hwnd);
  929.                if(Result)
  930.                   {
  931.                   DisplayError(hwnd, Result);
  932.                   LocalUnlock(hMem);
  933.                   break;
  934.                   }
  935.                SetCursor(hcurSaved);
  936.                LocalUnlock(hMem);
  937.                break;               
  938.  
  939.             case DVM_EXIT:
  940.                SendMessage(hwnd, WM_CLOSE, 0, 0L);
  941.                return(0);
  942.  
  943.             default:
  944.                return(DefWindowProc(hwnd, message, wParam, lParam));
  945.             }
  946.          break;
  947.  
  948.       case WM_ACTIVATE:
  949.          if(wParam && !HIWORD(lParam))            
  950.             hCurrentVideoWnd = hwnd;
  951.          break;
  952.  
  953.        case WM_PAINT:
  954.          hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  955.          pMem = LocalLock(hMem);
  956.          vData = (vidwin_t *)pMem;
  957.          wsprintf(Cmd, "update %s hdc 0",(LPSTR)vData->vIname);
  958.          LocalUnlock(hMem);
  959.          mciSendString(Cmd, Rtn, sizeof(Rtn), hwnd);
  960.          return(DefWindowProc(hwnd, message, wParam, lParam));
  961.  
  962.       case WM_CLOSE:
  963.  
  964.          // if a file is open, first close it 
  965.          
  966.          hMem = GetProp(hwnd,(LPSTR) szvPropEntry);
  967.          pMem = LocalLock(hMem);
  968.          vData = (vidwin_t *)pMem;
  969.          if(vData->State != SUSPENDED)
  970.             {
  971.             wsprintf(Cmd, "close %s",(LPSTR)vData->vIname);
  972.             Result = mciSendString(Cmd, Rtn, sizeof(Rtn), hwnd);
  973.             if(Result)
  974.                DisplayError(hwnd, Result);
  975.             }
  976.          LocalUnlock(hMem);
  977.          RemoveProp(hwnd,(LPSTR) szvPropEntry);
  978.          LocalFree(hMem);
  979.          FreeChildHandle(hwnd);
  980.          DestroyWindow(hwnd);
  981.          break;
  982.  
  983.       case WM_DESTROY:
  984.          break;
  985.  
  986.       default:
  987.          return(DefWindowProc(hwnd, message, wParam, lParam));
  988.       }
  989.  
  990.    return(0);
  991. }
  992.  
  993. /********************************************************************
  994.  
  995.    FUNCTION: UpdateMenus()
  996.  
  997. ********************************************************************/
  998. static void UpdateMenus(HWND hwnd)
  999. {
  1000.  
  1001.    HANDLE   hMem;
  1002.    PSTR     pMem;
  1003.    vidwin_t *vData;
  1004.  
  1005.    hMem = GetProp(hCurrentVideoWnd,(LPSTR) szvPropEntry);
  1006.    pMem = LocalLock(hMem);
  1007.    vData = (vidwin_t *)pMem;
  1008.  
  1009.    switch(vData->State)
  1010.       {
  1011.       case REWINDING:
  1012.       case STEPPING:
  1013.       case PAUSING:
  1014.  
  1015.          // executing a command, don't allow anything 
  1016.  
  1017.          EnableMenuItem(GetMenu(hwnd), DVM_OPEN,    MF_GRAYED);
  1018.          EnableMenuItem(GetMenu(hwnd), DVM_PLAY,    MF_GRAYED);
  1019.          EnableMenuItem(GetMenu(hwnd), DVM_PAUSE,   MF_GRAYED);
  1020.          EnableMenuItem(GetMenu(hwnd), DVM_STEP,    MF_GRAYED);
  1021.          EnableMenuItem(GetMenu(hwnd), DVM_REWIND,  MF_GRAYED);
  1022.          break;
  1023.  
  1024.       case END:
  1025.          // at end of file, can only rewind 
  1026.  
  1027.          EnableMenuItem(GetMenu(hwnd), DVM_OPEN,    MF_ENABLED);
  1028.          EnableMenuItem(GetMenu(hwnd), DVM_PLAY,    MF_GRAYED);
  1029.          EnableMenuItem(GetMenu(hwnd), DVM_PAUSE,   MF_GRAYED);
  1030.          EnableMenuItem(GetMenu(hwnd), DVM_STEP,    MF_GRAYED);
  1031.          EnableMenuItem(GetMenu(hwnd), DVM_REWIND,  MF_ENABLED);
  1032.          break;
  1033.  
  1034.       case PLAYING:
  1035.          // playing a file, only allow pausing 
  1036.  
  1037.          EnableMenuItem(GetMenu(hwnd), DVM_OPEN,    MF_GRAYED);
  1038.          EnableMenuItem(GetMenu(hwnd), DVM_PLAY,    MF_GRAYED);
  1039.          EnableMenuItem(GetMenu(hwnd), DVM_PAUSE,   MF_ENABLED);
  1040.          EnableMenuItem(GetMenu(hwnd), DVM_STEP,    MF_GRAYED);
  1041.          EnableMenuItem(GetMenu(hwnd), DVM_REWIND,  MF_GRAYED);
  1042.          break;
  1043.  
  1044.        case PAUSED:
  1045.          // Paused, allow open a new file, play, step, and rewind 
  1046.  
  1047.          EnableMenuItem(GetMenu(hwnd), DVM_OPEN,    MF_ENABLED);
  1048.          EnableMenuItem(GetMenu(hwnd), DVM_PLAY,    MF_ENABLED);
  1049.          EnableMenuItem(GetMenu(hwnd), DVM_PAUSE,   MF_GRAYED);
  1050.          EnableMenuItem(GetMenu(hwnd), DVM_STEP,    MF_ENABLED);
  1051.          EnableMenuItem(GetMenu(hwnd), DVM_REWIND,  MF_ENABLED);
  1052.          break;
  1053.    }
  1054.    LocalUnlock(hMem);
  1055.     DrawMenuBar(hwnd);
  1056. }
  1057.  
  1058. /********************************************************************
  1059.  
  1060.    FUNCTION: DisableMenus()
  1061.  
  1062. ********************************************************************/
  1063. static void DisableMenus(HWND hwnd)
  1064. {
  1065.    EnableMenuItem(GetMenu(hwnd), DVM_OPEN,    MF_GRAYED);
  1066.    EnableMenuItem(GetMenu(hwnd), DVM_PLAY,    MF_GRAYED);
  1067.    EnableMenuItem(GetMenu(hwnd), DVM_PAUSE,   MF_GRAYED);
  1068.    EnableMenuItem(GetMenu(hwnd), DVM_STEP,    MF_GRAYED);
  1069.    EnableMenuItem(GetMenu(hwnd), DVM_REWIND,  MF_GRAYED);
  1070.    DrawMenuBar(hwnd);
  1071. }
  1072.  
  1073. /********************************************************************
  1074.  
  1075.    FUNCTION: DisplayError(HWND, DWORD)
  1076.  
  1077.    PURPOSE:  Display Error messages
  1078.  
  1079. ********************************************************************/
  1080. static void DisplayError(HWND hwnd, DWORD Result)
  1081. {
  1082.    char ErrMsg[256];
  1083.  
  1084.    mciGetErrorString(Result, ErrMsg, sizeof(ErrMsg));
  1085.    MessageBox(hwnd, ErrMsg, szAppName, MB_OK);
  1086. }
  1087.  
  1088. BOOL GetFileName (LPSTR szFileName)
  1089. {
  1090.    OPENFILENAME   of;
  1091.    DWORD          flags;
  1092.    static char    szTitle[30];         // Dialog Box title
  1093.    static char    szFile[256];         // File name
  1094.    static char    szFileTitle[256];    // Title
  1095.    static char    szDrive[5];          // Drive
  1096.    static char    szDir[256];          // Directory
  1097.    static char    szFname[10];         // Filename
  1098.    static char    szExt[4];            // Extension
  1099.    static char    *szFilter[] =        // Filter
  1100.       {
  1101.       "AVSS Video",
  1102.       "*.avs",
  1103.       "AVI Video",
  1104.       "*.avi",
  1105.       ""
  1106.       };
  1107.  
  1108.  
  1109.    // Gets the default system directory for file open/save
  1110.  
  1111.    _getcwd (szDirName, sizeof (szDirName));
  1112.  
  1113.    // Initialize the OPENFILENAME members
  1114.  
  1115.    szFile[0] = '\0';
  1116.  
  1117.    lstrcpy(szTitle,"Load a Video File");
  1118.    flags = OFN_HIDEREADONLY;
  1119.  
  1120.    of.lStructSize       = sizeof (OPENFILENAME);
  1121.    of.hwndOwner         = GetFocus ();
  1122.    of.hInstance         = hInst;
  1123.    of.lpstrFilter       = szFilter[0];
  1124.    of.lpstrCustomFilter = NULL;
  1125.    of.nMaxCustFilter    = 0L;
  1126.    of.nFilterIndex      = 1L;
  1127.    of.lpstrFile         = szFile;
  1128.    of.nMaxFile          = sizeof (szFile);
  1129.    of.lpstrFileTitle    = szFileTitle;
  1130.    of.nMaxFileTitle     = sizeof (szFileTitle);
  1131.    of.lpstrInitialDir   = szDirName;
  1132.    of.lpstrTitle        = szTitle;
  1133.    of.Flags             = flags;
  1134.    of.nFileOffset       = 0;
  1135.    of.nFileExtension    = 0;
  1136.    of.lpstrDefExt       = NULL;
  1137.    of.lpfnHook              = NULL;
  1138.    of.lpTemplateName    = NULL;
  1139.  
  1140.    // Call the GetOpenFilename function
  1141.  
  1142.    if (GetOpenFileName (&of))
  1143.       {
  1144.       lstrcpy (szFileName, of.lpstrFile);
  1145.       return TRUE;
  1146.       }
  1147.    else
  1148.       return FALSE;
  1149. }
  1150.  
  1151. /********************************************************************
  1152.  
  1153.    FUNCTION: StoreChildHandle(HWND hwnd)
  1154.  
  1155.    PURPOSE:  Stores the newly created driver window handle in
  1156.              hArrVideoWnd[] at the next available slot and sets
  1157.              hCurrentVideoWnd to this window
  1158. ********************************************************************/
  1159. int StoreChildHandle(HWND hwnd)
  1160.  
  1161. {
  1162.    int   i;
  1163.  
  1164.    for(i=0;i<10;i++)
  1165.       if(hArrVideoWnd[i] == NULL)
  1166.          {
  1167.          hArrVideoWnd[i] = hwnd;
  1168.          break;
  1169.          }
  1170.    hCurrentVideoWnd = hwnd;
  1171.    return hwnd;
  1172. }
  1173. /********************************************************************
  1174.  
  1175.    FUNCTION: FreeChildHandle(HWND hwnd)
  1176.  
  1177.    PURPOSE:  Removes the entry for this driver window  from
  1178.              hArrVideoWnd[] 
  1179.  
  1180. ********************************************************************/
  1181. int FreeChildHandle(HWND hwnd)
  1182.  
  1183. {
  1184.    int   i;
  1185.  
  1186.    for(i=0;i<10;i++)
  1187.       if(hArrVideoWnd[i] == hwnd)
  1188.          {
  1189.          hArrVideoWnd[i] = NULL;
  1190.          break;
  1191.          }
  1192.    hCurrentVideoWnd = NULL;
  1193.    for(i=0;i<10;i++)
  1194.       if(hArrVideoWnd[i] != NULL)
  1195.          {
  1196.          hCurrentVideoWnd = hArrVideoWnd[i];
  1197.          SetFocus(hCurrentVideoWnd);
  1198.          UpdateWindow(hCurrentVideoWnd);        // Sends WM_PAINT message
  1199.          break;
  1200.          }
  1201.    return 1;
  1202. }
  1203. /********************************************************************
  1204.  
  1205.    FUNCTION: VidsOpen()
  1206.  
  1207.    PURPOSE:  Return the number of video windows open
  1208.  
  1209. ********************************************************************/
  1210. int VidsOpen(void)
  1211.  
  1212. {
  1213.    int   i,count;
  1214.    
  1215.    for(count=i=0;i<10;i++)
  1216.       if(hArrVideoWnd[i] != NULL)
  1217.          count++;
  1218.    return count;
  1219. }
  1220. /********************************************************************
  1221.  
  1222.    FUNCTION: AboutDlg(HWND, unsigned, WORD, LONG)
  1223.  
  1224.    PURPOSE:  Processes messages for "About" dialog box
  1225.  
  1226. ********************************************************************/
  1227. BOOL FAR PASCAL AboutDlg(HWND hDlg, unsigned message,
  1228.                         WORD wParam, LONG lParam)
  1229. {
  1230.    switch (message)
  1231.    {
  1232.       case WM_INITDIALOG :
  1233.          return (TRUE);
  1234.  
  1235.       case WM_COMMAND :
  1236.          if ((wParam == IDOK) ||
  1237.              (wParam == IDCANCEL))
  1238.          {
  1239.             EndDialog(hDlg, TRUE);
  1240.             return (TRUE);
  1241.          }
  1242.          break;
  1243.    }
  1244.  
  1245.    return (FALSE);
  1246. }
  1247.  
  1248. /********************************************************************
  1249.  
  1250.    FUNCTION: AboutDlg(HWND, unsigned, WORD, LONG)
  1251.  
  1252.    PURPOSE:  Processes messages for "About" dialog box
  1253.  
  1254. ********************************************************************/
  1255. BOOL FAR PASCAL DriverDlg(HWND hDlg, unsigned message,
  1256.                         WORD wParam, LONG lParam)
  1257. {
  1258.  
  1259.    static HWND hScroll;
  1260.    static int  uVolume;
  1261.    char        Cmd[256];
  1262.    char        Rtn[256];
  1263.    DWORD       Result;
  1264.    HANDLE      hMem;
  1265.    PSTR        pMem;
  1266.    vidwin_t    *vData;
  1267.  
  1268.    switch(message)
  1269.       {
  1270.       case WM_INITDIALOG:
  1271.          hMem = GetProp(hCurrentVideoWnd,(LPSTR) szvPropEntry);
  1272.          pMem = LocalLock(hMem);
  1273.          vData = (vidwin_t *)pMem;
  1274.          wsprintf(Cmd, "info %s product",(LPSTR)vData->vIname);
  1275.          Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hDlg);
  1276.          if(Result)
  1277.             {
  1278.             DisplayError(hDlg, Result);
  1279.             LocalUnlock(hMem);
  1280.             break;
  1281.             }
  1282.          SetDlgItemText(hDlg,IDM_PRODUCT,Rtn);
  1283.          wsprintf(Cmd, "info %s version",(LPSTR)vData->vIname);
  1284.          Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hDlg);
  1285.          if(Result)
  1286.             {
  1287.             DisplayError(hDlg, Result);
  1288.             LocalUnlock(hMem);
  1289.             break;
  1290.             }
  1291.          SetDlgItemText(hDlg,IDM_VERSION,Rtn);
  1292.          SetDlgItemText(hDlg,IDM_DRVFILE,vData->DVIFilename);
  1293.          wsprintf(Cmd, "status %s length",(LPSTR)vData->vIname);
  1294.          Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hDlg);
  1295.          if(Result)
  1296.             {
  1297.             DisplayError(hDlg, Result);
  1298.             LocalUnlock(hMem);
  1299.             break;
  1300.             }
  1301.          SetDlgItemText(hDlg,IDM_NOFRAMES,Rtn);
  1302.          wsprintf(Cmd, "status %s audio",(LPSTR)vData->vIname);
  1303.          Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hDlg);
  1304.          if(Result)
  1305.             {
  1306.             DisplayError(hDlg, Result);
  1307.             LocalUnlock(hMem);
  1308.             break;
  1309.             }
  1310.          if(!stricmp(Rtn,"on"))
  1311.             CheckDlgButton(hDlg,IDM_AUDIO,TRUE);
  1312.          wsprintf(Cmd, "status %s video",(LPSTR)vData->vIname);
  1313.          Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hDlg);
  1314.          if(Result)
  1315.             {
  1316.             DisplayError(hDlg, Result);
  1317.             LocalUnlock(hMem);
  1318.             break;
  1319.             }
  1320.          if(!stricmp(Rtn,"on"))
  1321.             CheckDlgButton(hDlg,IDM_VIDEO,TRUE);
  1322.          hScroll = GetDlgItem(hDlg,IDM_VOLUME);
  1323.          SetScrollRange(hScroll,SB_CTL,0,1000,TRUE);
  1324.          wsprintf(Cmd, "status %s volume",(LPSTR)vData->vIname);
  1325.          Result = mciSendString(Cmd,Rtn, sizeof(Rtn), hDlg);
  1326.          if(Result)
  1327.             {
  1328.             DisplayError(hDlg, Result);
  1329.             LocalUnlock(hMem);
  1330.             break;
  1331.             }
  1332.          uVolume = atoi(Rtn);
  1333.          SetScrollPos(hScroll,SB_CTL,uVolume,TRUE);
  1334.          LocalUnlock(hMem);
  1335.          return (TRUE);
  1336.  
  1337.       case  WM_HSCROLL:
  1338.          switch (wParam)
  1339.             {
  1340.             case  SB_THUMBPOSITION:
  1341.             case  SB_THUMBTRACK:
  1342.                SetScrollPos(hScroll,SB_CTL,LOWORD(lParam),TRUE);
  1343.                break;
  1344.             case  SB_PAGEDOWN:
  1345.                SetScrollPos(hScroll,SB_CTL,uVolume+100,TRUE);
  1346.                break;
  1347.             case  SB_PAGEUP:
  1348.                SetScrollPos(hScroll,SB_CTL,uVolume-100,TRUE);
  1349.                break;
  1350.             case  SB_LINEDOWN:
  1351.                SetScrollPos(hScroll,SB_CTL,uVolume+1,TRUE);
  1352.                break;
  1353.             case  SB_LINEUP:
  1354.                SetScrollPos(hScroll,SB_CTL,uVolume-1,TRUE);
  1355.                break;
  1356.             case  SB_BOTTOM:
  1357.                SetScrollPos(hScroll,SB_CTL,0,TRUE);
  1358.                break;
  1359.             case  SB_TOP:
  1360.                SetScrollPos(hScroll,SB_CTL,1000,TRUE);
  1361.                break;
  1362.             default:
  1363.                break;
  1364.             }
  1365.  
  1366.          hMem = GetProp(hCurrentVideoWnd,(LPSTR) szvPropEntry);
  1367.          pMem = LocalLock(hMem);
  1368.          vData = (vidwin_t *)pMem;
  1369.          uVolume = GetScrollPos(hScroll,SB_CTL);
  1370.          wsprintf(Cmd, "setaudio %s volume to %d",(LPSTR)vData->vIname,uVolume);
  1371.          Result = mciSendString(Cmd,Rtn, sizeof(Rtn), NULL);
  1372.          if(Result)
  1373.             {
  1374.             DisplayError(hDlg, Result);
  1375.             LocalUnlock(hMem);
  1376.             break;
  1377.             }
  1378.          LocalUnlock(hMem);
  1379.          return 0;
  1380.       case WM_COMMAND :
  1381.          switch (wParam)
  1382.             {
  1383.             case IDOK:
  1384.             case IDCANCEL:
  1385.             case IDM_OK:
  1386.                EndDialog(hDlg, TRUE);
  1387.                return (TRUE);
  1388.             case IDM_VIDEO:
  1389.                hMem = GetProp(hCurrentVideoWnd,(LPSTR) szvPropEntry);
  1390.                pMem = LocalLock(hMem);
  1391.                vData = (vidwin_t *)pMem;
  1392.                if(IsDlgButtonChecked(hDlg,IDM_VIDEO))
  1393.                   wsprintf(Cmd, "setvideo %s on",(LPSTR)vData->vIname);
  1394.                else
  1395.                   wsprintf(Cmd, "setvideo %s off",(LPSTR)vData->vIname);
  1396.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), NULL);
  1397.                if(Result)
  1398.                   {
  1399.                   DisplayError(hDlg, Result);
  1400.                   LocalUnlock(hMem);
  1401.                   break;
  1402.                   }
  1403.                LocalUnlock(hMem);
  1404.                break;
  1405.             case IDM_AUDIO:
  1406.                hMem = GetProp(hCurrentVideoWnd,(LPSTR) szvPropEntry);
  1407.                pMem = LocalLock(hMem);
  1408.                vData = (vidwin_t *)pMem;
  1409.                if(IsDlgButtonChecked(hDlg,IDM_AUDIO))
  1410.                   wsprintf(Cmd, "setaudio %s on",(LPSTR)vData->vIname);
  1411.                else
  1412.                   wsprintf(Cmd, "setaudio %s off",(LPSTR)vData->vIname);
  1413.                Result = mciSendString(Cmd,Rtn, sizeof(Rtn), NULL);
  1414.                if(Result)
  1415.                   {
  1416.                   DisplayError(hDlg, Result);
  1417.                   LocalUnlock(hMem);
  1418.                   break;
  1419.                   }
  1420.                LocalUnlock(hMem);
  1421.                break;
  1422.  
  1423.             case IDM_PLAY:
  1424.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_PLAY, 0L);
  1425.                break;
  1426.  
  1427.             case IDM_PAUSE:
  1428.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_PAUSE, 0L);
  1429.                break;
  1430.  
  1431.             case IDM_REWIND:
  1432.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_REWIND, 0L);
  1433.                break;
  1434.  
  1435.             case IDM_FRAME:
  1436.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_STEP, 0L);
  1437.                break;
  1438.  
  1439.             case IDM_REVERSE:
  1440.                SendMessage(hCurrentVideoWnd, WM_COMMAND, DVM_REVERSE, 0L);
  1441.                break;
  1442.             }
  1443.          break;   
  1444.       }
  1445.  
  1446.    return (FALSE);
  1447. }
  1448.  
  1449.